/* Include these
   #include <stdint.h>
   #include <stdlib.h> or something else with size_t
   #include <nit/list.h>
   #include <nit/hset.h>
   #include <nit/hmap.h>
   #include <nit/radix.h>
   #include <nit/vec.h>
*/

typedef struct ano_forms {
	Nit_list list;
	size_t end;
	void *val;
} Ano_form;

typedef struct ano_bin {
	Nit_dlist list;
	Ano_form *forms;
	size_t start;
} Ano_bin;

typedef struct ano_rilist {
	Nit_list list;
	Nit_radix_iter iter;
	size_t start;
} Ano_rilist;

/* Trie scan */
typedef struct ano_tscan {
	Nit_radix *radix;
	Ano_rilist *in_use;
	Ano_rilist *not_in_use;
	size_t pos;
} Ano_tscan;

typedef struct ano_ano {
	Ano_bin *bins;
	Ano_bin *end;
	Nit_vec vec;
} Ano_ano;

typedef enum { ANO_ERROR, ANO_FILTER, ANO_OK } Ano_stat;

typedef Ano_stat (*Ano_itemize)(void **val, void *context);
typedef int (*Ano_rank)(Ano_bin *bin, Ano_form *form, void *context);

typedef struct ano_reverb {
	void *context;
	Ano_itemize itemize;
	Ano_rank rank;
} Ano_reverb;

void
ano_tscan_init(Ano_tscan *scan, Nit_radix *radix);

int
ano_tscan_scan_unit(Ano_tscan *scan, Ano_ano *ano, Ano_reverb *reverb,
		    void *dat, size_t size);

/* void */
/* ano_tscan_predictions(Ano_tscan *scan, Nit_hmap_iter *iter); */

int
ano_ano_init(Ano_ano *ano, size_t size);

#ifdef ANO_SHORT_NAMES
# define tscan_init(...)      ano_tscan_init(__VA_ARGS__)
# define tscan_scan_unit(...) ano_tscan_scan_unit(__VA_ARGS__)
# define ano_init(...)        ano_ano_init(__VA_ARGS__)
#endif
